package com.cn.shuangzi.retrofit;


import com.cn.shuangzi.SZApp;
import com.cn.shuangzi.util.SZUtil;

import org.apaches.commons.codec.digest.DigestUtils;

import java.io.IOException;
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;


import okhttp3.FormBody;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;

/**
 * Created by CN on 2018-3-13.
 */

public class SZRequestInterceptor implements Interceptor {
    private String APP_ID = "0yfoZsFJJk7PeFwZ";
    private String APP_KEY = "AiPCKjWxSYCVJw9WS3kOqVuC8gZ7LFBq";

    public SZRequestInterceptor() {
    }

    public SZRequestInterceptor(String APP_ID, String APP_KEY) {
        this.APP_ID = APP_ID;
        this.APP_KEY = APP_KEY;
    }

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request original = chain.request();
        Request.Builder builder = original.newBuilder();
        original = builder.method(original.method(), original.body()).build();
        HttpUrl originalHttpUrl = original.url();
        SZUtil.logError("url:" + originalHttpUrl.url().toString());
        HttpUrl.Builder builderHttp = originalHttpUrl.newBuilder();
        long time = System.currentTimeMillis() / 1000;
        Map<String, Object> params = getParams(original);
        builderHttp.addQueryParameter("appId", APP_ID);
        builderHttp.addQueryParameter("appSignType","DIGEST");
        builderHttp.addQueryParameter("appTime",String.valueOf(time));
        builderHttp.addQueryParameter("appVersion",String.valueOf(SZUtil.getVersionCode()));
        params.put("appId", APP_ID);
        params.put("appSignType", "DIGEST");
        params.put("appTime", String.valueOf(time));
        params.put("appVersion", String.valueOf(SZUtil.getVersionCode()));

        if (SZApp.getInstance().getUserToken() != null) {
            builderHttp.addQueryParameter("appToken", SZApp.getInstance().getUserToken());
            params.put("appToken", SZApp.getInstance().getUserToken());
        }

        String appIdSZ = SZApp.getInstance().getSZAppId();
        if (appIdSZ != null) {
            builderHttp.addQueryParameter("applicationId", appIdSZ);
            params.put("applicationId", appIdSZ);
        }

        String channel = SZUtil.getChannel(SZApp.getInstance());
        if (channel != null) {
            builderHttp.addQueryParameter("channel", channel);
            params.put("channel", channel);
        }
        String data = transformationUri(sortMapByKey(params));
        String sign = DigestUtils.md5Hex(DigestUtils.sha1Hex(APP_KEY +
                data + APP_KEY ) + APP_ID);
        HttpUrl url = builderHttp.addQueryParameter("appSign", sign).build();
        Request.Builder requestBuilder = original.newBuilder()
                .url(url);
        Request request = requestBuilder.build();

//        if("POST".equals(request.method())){
//            StringBuilder sb = new StringBuilder();
//            if (request.body() instanceof FormBody) {
//                FormBody body = (FormBody) request.body();
//                for (int i = 0; i < body.size(); i++) {
//                    sb.append(body.encodedName(i) + "=" + body.encodedValue(i) + ",");
//                }
//                sb.delete(sb.length() - 1, sb.length());
//            }
//            SZUtil.log("postParams:"+sb);
//        }else{
//            SZUtil.log("getParams:"+originalHttpUrl.query());
//        }
        showParamsLog(request);
        return chain.proceed(request);
    }

    public static Map<String, Object> getParams(Request request) {
        Map<String, Object> params = new TreeMap<>();
        if (request.body() instanceof FormBody) {
            FormBody body = (FormBody) request.body();
            for (int i = 0; i < body.size(); i++) {
                params.put(body.name(i), body.value(i));
//                params.put(body.encodedName(i), body.encodedValue(i));
            }
        }
        for (String key : request.url().queryParameterNames()) {
            if (!params.containsKey(key)) {
                params.put(key, request.url().queryParameter(key));
            }
        }
        return params;
    }

    /**
     * 使用 Map按key进行排序
     *
     * @param map
     * @return
     */
    public static Map<String, Object> sortMapByKey(Map map) {
        if (map == null || map.isEmpty()) {
            return null;
        }
        Map<String, Object> sortMap = new TreeMap<>(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });
//        (o1, o2) -> o1.compareTo(o2)
        sortMap.putAll(map);
        return sortMap;
    }

    public static String transformationUri(Map<String, Object> map) {

        StringBuilder stringBuilder = new StringBuilder();

        for (String key : map.keySet()) {

            if ("appSign".equalsIgnoreCase(key)) {
                continue;
            }
            stringBuilder.append(key);
            stringBuilder.append("=");
            if (map.get(key).getClass().isArray()) {
                Object[] objects = (Object[]) map.get(key);
                StringBuilder valueBuilder = new StringBuilder();
                for (Object o : objects) {
                    valueBuilder.append(o);
                    valueBuilder.append(",");
                }
                valueBuilder.deleteCharAt(valueBuilder.length() - 1);
                stringBuilder.append(valueBuilder);
            } else {
                stringBuilder.append(map.get(key));
            }
            stringBuilder.append("&");
        }

        stringBuilder.deleteCharAt(stringBuilder.length() - 1);
        return stringBuilder.toString();
    }

    private void showParamsLog(Request request) {
        Map<String, Object> params = new TreeMap<>();
        if (request.body() instanceof FormBody) {
            FormBody body = (FormBody) request.body();
            for (int i = 0; i < body.size(); i++) {
                params.put(body.name(i), body.value(i));
            }
        }
        for (String key : request.url().queryParameterNames()) {
            if (!params.containsKey(key)) {
                params.put(key, request.url().queryParameter(key));
            }
        }
        StringBuilder sb = new StringBuilder();
        for (String name : params.keySet()) {
            sb.append(name + "=" + params.get(name) + ",");
        }
        if (sb.length() > 0) {
            sb.delete(sb.length() - 1, sb.length());
            SZUtil.logError("params:" + sb);
        }
    }
}
